type User = {
  id: number;
  name: string;
  preferences: {
    language: "en" | "es" | "fr";
    theme: "dark" | "light";
  };
  role: "user" | "admin";
  address: Array<{
    street: string;
    city: string;
    zipCode: string;
  }>;
};

const user1: User = {
  id: 0,
  name: "Columbus VonRueden",
  preferences: {
    language: "en",
    theme: "light",
  },
  role: "user",
  address: [
    {
      city: "London",
      street: "Baker Street",
      zipCode: "12345",
    },
  ],
};

user1["preferences"]["language"];
type User2 = typeof user1;
type Keys = keyof User;

function updateProperty<
  ObjectType extends object,
  ObjectKey extends keyof ObjectType
>(
  object: ObjectType,
  propertyUpdate: ObjectKey,
  newValue: ObjectType[ObjectKey]
): object {
  const newObj = { ...object, [propertyUpdate]: newValue };
  return newObj;
}

// 这里第三个参数取决于 你要修改哪个属性？如果是name，就直接传string就可以了
const result1 = updateProperty(user1, "preferences", {
  language: "fr",
  theme: "dark",
});
console.log(result1);

// For example挑战
const x = { a: 1, b: 2, c: 3, d: "4" };

function getProperty<x extends object, xKey extends keyof x>(
  x: x,
  key: xKey
): x[xKey] {
  return x[key];
}

const result2 = getProperty(x, "d");
console.log(result2);

export {};

export {};
